import { StatusCode } from "./web-result";
import WebResult from "./web-result";
import ls from "../local-storage";
import { getUserInfo } from "./user";

export class QuestionType {
    static SINGLE_CHOICE = new QuestionType("单选题");         // 单选题
    static MULTIPLE_CHOICE = new QuestionType("多选题");       // 多选题
    static JUDGEMENT = new QuestionType("判断题");             // 判断题
    static FILL_IN_THE_BLANK = new QuestionType("填空题");     // 填空题
    static SHORT_ANSWER = new QuestionType("简答题");          // 简答题

    constructor(value) {
        this.value = value.toString();
    }

    toString() {
        return this.value;
    }
}

export class Question {
    /**
     *
     * @param { string } title
     * @param { string } description
     * @param { QuestionType } questionType question type
     * @param { string[] } questionContent ["选项一", "选项二"] ["你是", "", "，今年", ""， "岁"]
     */
    constructor(title, description, questionType, questionContent) {
        this.title = title;
        this.description = description;
        this.type = questionType;
        // 简答题没有 content
        this.content = [];
        if (this.type !== QuestionType.SHORT_ANSWER) {
            this.content = questionContent;
        }
    }
}

export class QuestionAnswer {

    /**
     * @param { Question } question question
     * @param { any[] } answer [0] [0, 1] ["小明", "18"] [true, false] ["回答这个简答题"]
     */
    constructor(question, answer) {
        if (!Array.isArray(answer) || !answer || answer.length === 0) {
            throw new Error("错误的 answer");
        }
        this.answer = answer;
        switch(question.type) {
            case QuestionType.SINGLE_CHOICE:
                if (typeof answer[0] !== "number") {
                    throw new Error("错误的 answer");
                }
                if (answer[0] > question.content.length - 1) {
                    throw new Error("错误的 answer");
                }
                break;
            case QuestionType.MULTIPLE_CHOICE:
                for (const a of answer) {
                    if (typeof a !== "number") {
                        throw new Error("错误的 answer");
                    }
                    if (a > question.content.length - 1) {
                        throw new Error("错误的 answer");
                    }
                }
                break;
            case QuestionType.JUDGEMENT:
                for (const a of answer) {
                    if (typeof a !== "boolean") {
                        throw new Error("错误的 answer");
                    }
                }
                break;
            case QuestionType.FILL_IN_THE_BLANK:
                for (const a of answer) {
                    if (typeof a !== "string") {
                        throw new Error("错误的 answer");
                    }
                }
                break;
            case QuestionType.SHORT_ANSWER:
                if (typeof answer[0] !== "string") {
                    throw new Error("错误的 answer");
                }
                break;
            default:
                throw new Error("错误的question type");
        }
    }
}


export class WJAnswer {
    /**
     * @param { string } username
     * @param { QuestionAnswer[] } answers answer list
     */
    constructor(username, answers) {
        this.username = username;
        this.answers = answers;
        const nowDate = new Date();
        this.time = nowDate.toLocaleDateString + " " + nowDate.toLocaleTimeString();
    }
}


export class WJ {

    /**
     * @param { string } creator username
     * @param { string } title 问卷标题
     * @param { Question[] } questions questions
     */
    constructor(creator, title, description, questions) {
        this.creator = creator;
        this.title = title;
        this.description = description;
        this.date = new Date().toLocaleDateString();
        this.question = questions;
    }
}


const WJSaver = {

    saveName: "wj",

    has(wj) {
        const username = wj.creator;
        const list = WJSaver.getListByUsername(username);
        if (list.find(item => item.title === wj.title)) {
            return true;
        }
        return false;
    },

    /**
     * @param { string } username
     * @param { WJ } wj
     */
    saveOne(wj) {
        let wjObj = ls.get(WJSaver.saveName);
        if (!wjObj) {
            wjObj = {};
        }
        if (!wjObj[wj.creator]) {
            wjObj[wj.creator] = [];
        }
        const list = wjObj[wj.creator];
        for (let i = 0; i < list.length; i++) {
            if (list[i].title === wj.title) {
                list[i] = wj;
                ls.set(WJSaver.saveName, wjObj);
                return;
            }
        }
        list.push(wj);
        ls.set(WJSaver.saveName, wjObj);
    },

    getOne(username, title) {
        const wjObj = ls.get(WJSaver.saveName);
        if (!wjObj) {
            return null;
        }
        if (!wjObj[username]) {
            return null;
        }
        const wj = wjObj[username].find(item => item.title === title);
        if (!wj) {
            return null;
        }
        return wj;
    },

    deleteOne(wj) {
        let wjObj = ls.get(WJSaver.saveName);
        if (!wjObj) {
            return;
        }
        const wjList = WJSaver.getListByUsername(wj.creator);
        for (let i = 0; i < wjList.length; i++) {
            if (wjList[i].title === wj.title) {
                wjList.splice(i, 1);
                wjObj[wj.creator] = wjList;
                ls.set(WJSaver.saveName, wjObj);
            }
        }
    },


    getOneByUsernameAndTitle(creator, title) {
        const wjList = WJSaver.getListByUsername(creator);
        const wj = wjList.find(item => item.title === title);
        if (!wj) {
            return null;
        }
        return wj;
    },
    getListByUsername(username) {
        const wjObj = ls.get(WJSaver.saveName);
        if (!wjObj) {
            return [];
        }
        return wjObj[username] ? wjObj[username] : [];
    },

    getList() {
        const wjObj = ls.get(WJSaver.saveName);
        if (!wjObj) {
            return [];
        }
        const list = Object.values(wjObj).flat();
        if (!list) {
            return [];
        }
        return list;
    }
};


// {
//     creator: {
//         title: [ answer对象 ]
//     }
// }
const WJAnswerSaver = {
    saveName: "wj_answer",

    has(wj, username) {
        const wjAnswerObj = ls.get(WJAnswerSaver.saveName);
        if (!wjAnswerObj) {
            return false;
        }
        if (!wjAnswerObj[wj.creator]) {
            return false;
        }
        const answerObj = wjAnswerObj[wj.creator];
        if (!answerObj[wj.title]) {
            return false;
        }
        if (answerObj[wj.title].find(item => item.username === username)) {
            return true;
        }
        return false;
    },

    saveOne(wj, wjAnswer) {
        let wjAnswerObj = ls.get(WJAnswerSaver.saveName);
        if (!wjAnswerObj) {
            wjAnswerObj = {};
        }
        if (!wjAnswerObj[wj.creator]) {
            wjAnswerObj[wj.creator] = {};
        }
        if (!wjAnswerObj[wj.creator][wj.title]) {
            wjAnswerObj[wj.creator][wj.title] = [];
        }
        // 替换已经有的
        for (let i = 0; i < wjAnswerObj[wj.creator][wj.title].length; i++) {
            if (wjAnswerObj[wj.creator][wj.title][i].username === wjAnswer.username) {
                wjAnswerObj[wj.creator][wj.title][i] = wjAnswer;
                ls.set(WJAnswerSaver.saveName, wjAnswerObj);
                return;
            }
        }
        wjAnswerObj[wj.creator][wj.title].push(wjAnswer);
    },

    getOne(wj, username) {
        const wjAnswerObj = ls.get(WJAnswerSaver.saveName);
        if (!wjAnswerObj) {
            return null;
        }
        if (!wjAnswerObj[wj.creator]) {
            return null;
        }
        if (!wjAnswerObj[wj.creator][wj.title]) {
            return null;
        }
        const answer = wjAnswerObj[wj.creator][wj.title].find(item => item.username === username);
        if (!answer) {
            return null;
        }
        return answer;
    },

    getList(wj) {
        const wjAnswerObj = ls.get(WJAnswerSaver.saveName);
        if (!wjAnswerObj) {
            return [];
        }
        if (!wjAnswerObj[wj.creator]) {
            return [];
        }
        if (!wjAnswerObj[wj.creator][wj.title]) {
            return [];
        }
        return wjAnswerObj[wj.creator][wj.title];
    },
    getListByUsername(username) {
        const wjAnswerObj = ls.get(WJAnswerSaver.saveName);
        if (!wjAnswerObj) {
            return [];
        }
        const answerObjArray = Object.values(wjAnswerObj);
        if (!answerObjArray) {
            return [];
        }
        const answerArrayArray = new Array(answerObjArray.length);
        for (let i = 0; i < answerObjArray.length; i++) {
            answerArrayArray[i] = Object.values(answerObjArray[i]);
        }
        return answerArrayArray.flat(2).filter(item => item.username === username);
    },

    deleteOne(wj, username) {
        const wjAnswerObj = ls.get(WJAnswerSaver.saveName);
        if (!wjAnswerObj) {
            return;
        }
        if (!wjAnswerObj[wj.creator]) {
            return;
        }
        if (!wjAnswerObj[wj.creator][wj.title]) {
            return;
        }
        for (let i = 0; i < wjAnswerObj[wj.creator][wj.title].length; i++) {
            if (wjAnswerObj[wj.creator][wj.title][i].username === username) {
                wjAnswerObj[wj.creator][wj.title].splice(i, 1);
                ls.set(WJAnswerSaver.saveName, wjAnswerObj);
                return;
            }
        }
    }
}


export async function getWJList() {
    return WebResult.success(WJSaver.getList());
}
export async function getWJListByUsername(username) {
    return WebResult.success(WJSaver.getListByUsername(username));
}


/**
 * @param { WJ } wj 问卷对象
 */
export async function createWJ(wj) {
    const result = await getUserInfo();
    if (result.code === StatusCode.FAILED) {
        return WebResult.failed();
    }
    const user = result.data;
    wj.creator = user.username;
    if (WJSaver.has(wj)) {
        return WebResult.success(undefined, "问卷已存在");
    }
    WJSaver.saveOne(wj);
    return WebResult.success(undefined, "创建成功");
}

/**
 * @param { WJ } wj 问卷对象
 */
export async function updateWJ(updateWJ) {
    const result = await getUserInfo();
    if (result.code === StatusCode.FAILED) {
        return WebResult.failed();
    }
    const user = result.data;
    if (user.username !== updateWJ.creator) {
        return WebResult.failed(undefined, "没有权限");
    }
    if (!WJSaver.has(updateWJ)) {
        return WebResult.failed(undefined, "要更新的问卷不存在");
    }
    WJSaver.saveOne(updateWJ);
    return WebResult.success(undefined, "更新成功");
}

/**
 * @param { WJ } wj 问卷对象
 */
export async function deleteWJ(deleteWJ) {
    const result = await getUserInfo();
    if (result.code === StatusCode.FAILED) {
        return WebResult.failed();
    }
    const user = result.data;
    if (user.username !== deleteWJ.creator) {
        return WebResult.failed(undefined, "没有权限");
    }

    if (!!WJSaver.has(updateWJ)) {
        return WebResult.failed(undefined, "要删除的问卷不存在");
    }
    WJSaver.deleteOne(deleteWJ);
    return WebResult.success(undefined, "删除成功");
}

export async function getWJByUsernameAndTitle(creator, title) {
    const wj = WJSaver.getOneByUsernameAndTitle(creator, title);
    if (!wj) {
        return WebResult.failed(undefined, "查找的问卷不存在");
    }
    return WebResult.success(wj);
}

/**
 * @param { WJ } wj
 * @param { WJAnswer } wjAnswer
 */
export async function answerWJ(wj, wjAnswer) {
    if (WJAnswerSaver.has(wj, wjAnswer.username)) {
        return WebResult.failed(undefined, "已经回答过该问卷");
    }
    WJAnswerSaver.saveOne(wj, wjAnswer);
    return WebResult.success(undefined, "回答成功");
}

export async function getWJAnswerList() {
    const result = await getUserInfo();
    if (!result.code === StatusCode.FAILED) {
        return WebResult.failed(undefined, "没有权限");
    }
    const user = result.data;
    return WebResult.success(WJAnswerSaver.getListByUsername(user.username));
}

